package com.tjkcht.midware.reader;

import java.util.HashMap;
import java.util.Map;
import java.util.logging.Logger;

import com.shhic.itsed.mws.deviceintf.IDeviceIntf;
import com.shhic.itsed.mws.deviceintf.IReaderResultCallback;
import com.shhic.itsed.mws.deviceintf.ReaderCommand;
import com.shhic.itsed.mws.deviceintf.ReaderLinkStatusEnum;

import io.netty.bootstrap.Bootstrap;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioSocketChannel;
import rdp_msg.Rdp.rdp_request;
import rdp_msg.Rdp.rdp_request.Builder;
import rdp_msg.Rdp.rdp_request.HeadType;

// TODO: Auto-generated Javadoc
/**
 * Rd30阅读器管理.
 */
public class Rd30Manager implements IDeviceIntf {

	/** The map. */
	private Map<String, IReader> map = new HashMap<String, IReader>();

	/** The group. */
	private EventLoopGroup group = new NioEventLoopGroup();

	/** The bootstrap. */
	private Bootstrap bootstrap;

	/** The log. */
	private Logger log = Logger.getLogger("Rd30Manager");

	/** 断链重连等待时间(s). */
	private int WAIT_TIME = 10;

	/**
	 * Instantiates a new reader manager.
	 */
	public Rd30Manager() {
		bootstrap = new Bootstrap().group(group).channel(NioSocketChannel.class)
				.handler(new ReaderChannelInitializer(this));
	}

//	public Bootstrap getBs() {
//		EventLoopGroup group1 = new NioEventLoopGroup();
//		Bootstrap bs = new Bootstrap().group(group1).channel(NioSocketChannel.class)
//				.handler(new ReaderChannelInitializer(this));
//		return bs;
//	}

	/**
	 * Gets the reader.
	 *
	 * @param readerIp
	 *            the reader ip
	 * @return the reader
	 */
	public IReader getReader(String readerIp) {
		return map.get(readerIp);
	}

	/**
	 * Gets the wait time.
	 *
	 * @return the wait time
	 */
	public int getWAIT_TIME() {
		return WAIT_TIME;
	}

	/**
	 * Sets the wait time.
	 *
	 * @param wAIT_TIME
	 *            the new wait time
	 */
	public void setWAIT_TIME(int wAIT_TIME) {
		WAIT_TIME = wAIT_TIME;
	}

	/**
	 * 关闭所有的阅读器.
	 */
	public synchronized void close() {
		for (IReader reader : map.values()) {
			reader.disconnect();
		}
		map.clear();
		group.shutdownGracefully();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.shhic.itsed.mws.deviceintf.IDeviceIntf#disconnectReader(java.lang.
	 * String)
	 */
	public synchronized void disconnectReader(String readerIp) {
		if (map.containsKey(readerIp)) {
			map.get(readerIp).disconnect();
			map.remove(readerIp);
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.shhic.itsed.mws.deviceintf.IDeviceIntf#dispatchReadCommand(java.lang.
	 * String, com.shhic.itsed.mws.deviceintf.ReaderCommand, int,
	 * com.shhic.itsed.mws.deviceintf.IReaderResultCallback)
	 */
	public synchronized void dispatchReadCommand(String readerIp, ReaderCommand cmd, int timeout,
			IReaderResultCallback resultCallback) {
		if (map.containsKey(readerIp)) {
			// timeout如何处理？
			((Rd30Reader) map.get(readerIp)).write(cmd, timeout, resultCallback);
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.shhic.itsed.mws.deviceintf.IDeviceIntf#initReader(java.lang.String,
	 * int)
	 */
	public void initReader(String readerIp, int port) {
		initReader(readerIp, port, getDefaultInitParams());
	}

	/* 
	 * 阅读器默认配置参数值
	 * 	initParams.put("freq", "922625");
		initParams.put("power", "14");
		initParams.put("code_type", "0");
		initParams.put("forward_rate", "80");
		initParams.put("reverse_rate", "160");
	 */
	public synchronized void initReader(String readerIp, int port, Map<String, String> initParams) {
		if (null == initParams) {
			initParams = getDefaultInitParams();
		}
		if (!map.containsKey(readerIp)) {
			Rd30Reader reader = new Rd30Reader(bootstrap, readerIp, port, initParams);
//			Rd30Reader reader = new Rd30Reader(getBs(), readerIp, port, initParams);
			map.put(readerIp, reader);
			try {
				reader.connect();
			} catch (InterruptedException e) {
				log.warning(e.getMessage());
			}
		}
	}

	/**
	 * Gets the default init params.
	 *
	 * @return the default init params
	 */
	protected Map<String, String> getDefaultInitParams() {
		Map<String, String> initParams = new HashMap<String, String>();
		initParams.put("freq", "922625");
		initParams.put("power", "14");
		initParams.put("code_type", "0");
		initParams.put("forward_rate", "80");
		initParams.put("reverse_rate", "160");
		return initParams;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.shhic.itsed.mws.deviceintf.IDeviceIntf#queryDeviceLinkstatus(java.
	 * lang.String)
	 */
	public ReaderLinkStatusEnum queryDeviceLinkstatus(String readerIp) {
		if (map.containsKey(readerIp)) {
			return map.get(readerIp).getStatus();
		} else {
			return null;
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.shhic.itsed.mws.deviceintf.IDeviceIntf#stopReaderCommand(java.lang.
	 * String)
	 */
	public synchronized void stopReaderCommand(String readerIp) {
		if (!map.containsKey(readerIp)) {
			return;
		}
		Builder setReq = rdp_request.newBuilder();
		setReq.setType(HeadType.stopReaderWork);
		log.info("stop reader:" + readerIp);
		map.get(readerIp).write(setReq.build().toByteArray());
	}
}
